function Y = ga(X, cloneRatio)
% genetic algorithm implement
    % reverse sort by 3rd row
    X = sortrows(X, -3);
    % ###### clone ########
    [m1, n1] = size(X);
    nc = ceil(m1 * cloneRatio);
    C = X(1: nc, :);

    % die after clone
    X(1: nc, :) = [];

    % ### Sexual propagation ###
    [m, n] = size(X);
    % mutation ratio
    r = mutationRatio(X(:, 3));
    % normalize fitness
    X(:, 3) = X(:, 3) ./ (sum(X(:, 3)) + eps);
    % compute difference
    Cov = X(:, 1: 2) * X(:, 1: 2)';

    % init baby bed
    B = zeros(m, n);
    % get married and have two babies
    for k = 1: m
        % one husband one wife
        X(k, 3) = -1;
        % find most different one
        row = Cov(k, :);
        % normalize then add fitness
        row = row / sum(row) + X(:, 3)';
        [value, index] = max(row);
        % mating
        v1 = X(k, :);
        v2 = X(index, :);
        % welcome baby
        B(2 * k - 1, :) = [v1(1), v2(2), 0];
        B(2 * k, :) = [v2(1), v1(2), 0];
    end

    % mutation
    B = mutation(B, r);

    % children replace parents
    Y = [C; B];
    Y(m1 + 1: end, :) = [];
    Y(:, 3) = fitness(Y(:, 1), Y(:, 2));
    % double
    Y = [Y; Y];   
    
    % natural selection
    % Y = naturalSelection(Y);
end